package lp2.projeto.gerenciador;
import java.io.Serializable;
import java.util.*;

/**
 * Classe responsavel pelo armazenamento de eventos e contatos. Tambem responsavel pela manipulacao dos mesmos.
 *
 */
public class Gerenciador implements Serializable {
	private static final long serialVersionUID = -2073473097407386473L;
	private HashMap<Evento, ArrayList<Contato>> mapaEventos = new HashMap<Evento, ArrayList<Contato>>();
	private HashMap<Contato, ArrayList<Evento>> mapaContatos = new HashMap<Contato, ArrayList<Evento>>();
	/**
	 * Adiciona um novo evento ao mapa de eventos do gerenciador.
	 * @param e Evento a ser adicionado
	 * @return toString do evento adicionado
	 */
	public String adicionaEvento(Evento e){
		mapaEventos.put(e, new ArrayList<Contato>());
		String retorno = "";
		for (Evento evento : mapaEventos.keySet()){
			retorno += evento.toString() + "/";
		}
		return retorno;
	}
	/**
	 * Adiciona um novo contato ao mapa de contatos do gerenciador.
	 * @param c Contato a ser adicionado
	 */
	public void adicionaContato(Contato c){

		 if (!mapaContatos.containsKey(c))
			 mapaContatos.put(c, new ArrayList<Evento>());
	 }
	 /**
	  * Adiciona um contato ao evento. 
	  * @param c Contato a ser adicionado
	  * @param e Evento que recebe o contato
	  * @return true se foi possivel adicionar, false se jah estava adicionado
	  */
	public boolean adicionaContatoAEvento(Contato c, Evento e){
		 if (!mapaEventos.get(e).contains(c)) {
			 mapaEventos.get(e).add(c);
			 mapaContatos.get(c).add(e);
			 return true;
		 }
		 return false;
	 }
	 /**
	  * Retorna uma lista de contatos que comecem com o nome especificado.
	  * @param nome Nome para busca de contato
	  * @return Lista de contatos 
	  */
	public List<Contato> buscaContatoPorNome(String nome){

		 List<Contato> contatosEspecificos = new ArrayList<Contato>();
		 for (Contato contato : mapaContatos.keySet()){
			 if (contato.getNome().toLowerCase().startsWith(nome.toLowerCase())){
				 contatosEspecificos.add(contato);
			 }
		 }
		 return contatosEspecificos; 
	 }
	 /**
	  * Get dos contatos do gerenciador.
	  * @return Lista de contatos do gerenciador
	  */
	public List<Contato> getContatos(){

		return new ArrayList<Contato>(mapaContatos.keySet());	 
	 }
	 /**
	  * Get dos eventos do gerenciador.
	  * @return Lista de eventos do gerenciador
	  */
	public List<Evento> getEventos(){

		 return new ArrayList<Evento>(mapaEventos.keySet());	 
	 }
	
	public void removeEvento(Evento e) {
		for(Evento event : mapaEventos.keySet())
			if(e.equals(event)) {
				mapaEventos.remove(event);
				break;
			}

		for (ArrayList<Evento> listaDeEventos : mapaContatos.values()) {
			for (Evento evento: listaDeEventos)
				if (evento.equals(e)) {
					listaDeEventos.remove(e);
					break;
				}
		}
	}
	
	/**
	 * Remove contato especificado.
	 * @param c Contato a ser removido
	 */
	public void removeContato(Contato c){


		 for (Contato contato : mapaContatos.keySet()){
			 if (contato.equals(c)){
				 mapaContatos.remove(c);
				 break;
			 }
			
		 }
		 for (ArrayList<Contato> listaDeContatos : mapaEventos.values()){
			 for (Contato contato : listaDeContatos){
				 if (contato.equals(c)){
					 listaDeContatos.remove(c);
					 break;
				 } 
			 }	 
		 }
	 }
	/**
	 * Get dos eventos que contenham determinado contato.
	 * @param c Contato para busca de eventos
	 * @return Lista de eventos
	 */
	public List<Evento> getEventoPorContato(Contato c){
		return mapaContatos.get(c);
	 }
	/**
	 * Get dos eventos que contenham determinado evento.
	 * @param e Evento para busca de contato
	 * @return Lista de contatos
	 */
	public List<Contato> getContatoPorEvento(Evento e){
		 return mapaEventos.get(e);
	 }
	
	public List<Evento> buscaEventoPorNome(String nome) {

		 List<Evento> contatosEspecificos = new ArrayList<Evento>();
		 for (Evento evento : mapaEventos.keySet()){
			 if (evento.getNome().toLowerCase().startsWith(nome.toLowerCase())){
				 contatosEspecificos.add(evento);
			 }
		 }
		 return contatosEspecificos; 
	}
	
	/**
	 * Remove o contato de um evento
	 * @param contato o contato
	 * @param evento o evento
	 */
	public void removeContatoDeEvento(Contato contato, Evento evento) {
		mapaEventos.get(evento).remove(contato);
		mapaContatos.get(contato).remove(evento);
	}
}
	
	

